#include "../BindPugiXML.hpp"

using namespace luabind;
namespace bind
{
	namespace pugi
	{
		void Bind(lua_State* lua, const std::string& ns)
		{
			//globals(lua)[ns.c_str()] = newtable(lua);
				
			module(lua, ns.c_str())
				[
					class_<::pugi::xml_writer_file>("writer_file")
						.def(constructor<void*>())
						.def("write", &::pugi::xml_writer_file::write),

					class_<::pugi::xml_writer_stream>("writer_stream")
						.def(constructor<std::basic_ostream<char, std::char_traits<char> >&>())
						.def(constructor<std::basic_ostream<wchar_t, std::char_traits<wchar_t> >&>())
						.def("write", &::pugi::xml_writer_stream::write),

					class_<::pugi::xml_attribute_struct>("attribute_struct"),

					class_<::pugi::xml_attribute>("attribute")
						.def(constructor<>())
						.def("empty", &::pugi::xml_attribute::empty)
						.def("name", &::pugi::xml_attribute::name)
						.def("value", &::pugi::xml_attribute::value)
						.def("as_int", &::pugi::xml_attribute::as_int)
						.def("as_uint", &::pugi::xml_attribute::as_uint)
						.def("as_double", &::pugi::xml_attribute::as_double)
						.def("as_float", &::pugi::xml_attribute::as_float)
						.def("as_bool", &::pugi::xml_attribute::as_bool)
						.def("set_name", &::pugi::xml_attribute::set_name)
						.def("set_value", (bool(::pugi::xml_attribute::*)(const ::pugi::char_t*))&::pugi::xml_attribute::set_value)
						.def("set_value", (bool(::pugi::xml_attribute::*)(int))&::pugi::xml_attribute::set_value)
						.def("set_value", (bool(::pugi::xml_attribute::*)(unsigned int))&::pugi::xml_attribute::set_value)
						.def("set_value", (bool(::pugi::xml_attribute::*)(double))&::pugi::xml_attribute::set_value)
						.def("set_value", (bool(::pugi::xml_attribute::*)(bool))&::pugi::xml_attribute::set_value)
						.def("next_attribute", &::pugi::xml_attribute::next_attribute)
						.def("previous_attribute", &::pugi::xml_attribute::previous_attribute)
						.def("hash_value", &::pugi::xml_attribute::hash_value)
						/*.def("internal_object", &::pugi::xml_attribute::internal_object)*/,

					class_<::pugi::xml_node_struct>("node_struct"),

					class_<::pugi::xml_node>("node")
						.def(constructor<>())
						.def("empty", &::pugi::xml_node::empty)
						.def("type", &::pugi::xml_node::type)
						.def("name", &::pugi::xml_node::name)
						.def("value", &::pugi::xml_node::value)
						.def("first_attribute", &::pugi::xml_node::first_attribute)
						.def("last_attribute", &::pugi::xml_node::last_attribute)
						.def("first_child", &::pugi::xml_node::first_child)
						.def("last_child", &::pugi::xml_node::last_child)
						.def("next_sibling", (::pugi::xml_node(::pugi::xml_node::*)()const)&::pugi::xml_node::next_sibling)
						.def("next_sibling", (::pugi::xml_node(::pugi::xml_node::*)(const ::pugi::char_t*)const)&::pugi::xml_node::next_sibling)
						.def("previous_sibling", (::pugi::xml_node(::pugi::xml_node::*)()const)&::pugi::xml_node::previous_sibling)
						.def("previous_sibling", (::pugi::xml_node(::pugi::xml_node::*)(const ::pugi::char_t*)const)&::pugi::xml_node::previous_sibling)
						.def("parent", &::pugi::xml_node::parent)
						.def("root", &::pugi::xml_node::root)
						.def("child", &::pugi::xml_node::child)
						.def("attribute", &::pugi::xml_node::attribute)
						.def("child_value", (const ::pugi::char_t*(::pugi::xml_node::*)()const)&::pugi::xml_node::child_value)
						.def("child_value", (const ::pugi::char_t*(::pugi::xml_node::*)(const ::pugi::char_t*)const)&::pugi::xml_node::child_value)
						.def("set_name", &::pugi::xml_node::set_name)
						.def("set_value", &::pugi::xml_node::set_value)
						.def("append_attribute", &::pugi::xml_node::append_attribute)
						.def("prepend_attribute", &::pugi::xml_node::prepend_attribute)
						.def("insert_attribute_after", &::pugi::xml_node::insert_attribute_after)
						.def("insert_attribute_before", &::pugi::xml_node::insert_attribute_before)
						.def("append_copy", (::pugi::xml_attribute(::pugi::xml_node::*)(const ::pugi::xml_attribute&))&::pugi::xml_node::append_copy)
						.def("append_copy", (::pugi::xml_node(::pugi::xml_node::*)(const ::pugi::xml_node&))&::pugi::xml_node::append_copy)
						.def("prepend_copy", (::pugi::xml_attribute(::pugi::xml_node::*)(const ::pugi::xml_attribute&))&::pugi::xml_node::prepend_copy)
						.def("prepend_copy", (::pugi::xml_node(::pugi::xml_node::*)(const ::pugi::xml_node&))&::pugi::xml_node::prepend_copy)
						.def("insert_copy_after", (::pugi::xml_attribute(::pugi::xml_node::*)(const ::pugi::xml_attribute&, const ::pugi::xml_attribute&))&::pugi::xml_node::insert_copy_after)
						.def("insert_copy_after", (::pugi::xml_node(::pugi::xml_node::*)(const ::pugi::xml_node&, const ::pugi::xml_node&))&::pugi::xml_node::insert_copy_after)
						.def("insert_copy_before", (::pugi::xml_attribute(::pugi::xml_node::*)(const ::pugi::xml_attribute&, const ::pugi::xml_attribute&))&::pugi::xml_node::insert_copy_before)
						.def("insert_copy_before", (::pugi::xml_node(::pugi::xml_node::*)(const ::pugi::xml_node&, const ::pugi::xml_node&))&::pugi::xml_node::insert_copy_before)
						.def("append_child", (::pugi::xml_node(::pugi::xml_node::*)(const ::pugi::char_t*))&::pugi::xml_node::append_child)
						.def("append_child", (::pugi::xml_node(::pugi::xml_node::*)(::pugi::xml_node_type))&::pugi::xml_node::append_child)
						.def("prepend_child", (::pugi::xml_node(::pugi::xml_node::*)(const ::pugi::char_t*))&::pugi::xml_node::prepend_child)
						.def("prepend_child", (::pugi::xml_node(::pugi::xml_node::*)(::pugi::xml_node_type))&::pugi::xml_node::prepend_child)
						.def("insert_child_after", (::pugi::xml_node(::pugi::xml_node::*)(const ::pugi::char_t*, const ::pugi::xml_node&))&::pugi::xml_node::insert_child_after)
						.def("insert_child_after", (::pugi::xml_node(::pugi::xml_node::*)(::pugi::xml_node_type, const ::pugi::xml_node&))&::pugi::xml_node::insert_child_after)
						.def("insert_child_before", (::pugi::xml_node(::pugi::xml_node::*)(const ::pugi::char_t*, const ::pugi::xml_node&))&::pugi::xml_node::insert_child_before)
						.def("insert_child_before", (::pugi::xml_node(::pugi::xml_node::*)(::pugi::xml_node_type, const ::pugi::xml_node&))&::pugi::xml_node::insert_child_before)
						.def("remove_attribute", (bool(::pugi::xml_node::*)(const ::pugi::xml_attribute&))&::pugi::xml_node::remove_attribute)
						.def("remove_attribute", (bool(::pugi::xml_node::*)(const ::pugi::char_t*))&::pugi::xml_node::remove_attribute)
						.def("remove_child", (bool(::pugi::xml_node::*)(const ::pugi::xml_node&))&::pugi::xml_node::remove_child)
						.def("remove_child", (bool(::pugi::xml_node::*)(const ::pugi::char_t*))&::pugi::xml_node::remove_child)
						// find Methode mit Template
						.def("print", (void(::pugi::xml_node::*)(::pugi::xml_writer&, const ::pugi::char_t*, unsigned int, ::pugi::xml_encoding, unsigned int)const)&::pugi::xml_node::print)
						.def("begin", &::pugi::xml_node::begin)
						.def("end", &::pugi::xml_node::end)
						.def("attributes_begin", &::pugi::xml_node::attributes_begin)
						.def("attributes_end", &::pugi::xml_node::attributes_end)
						.def("offset_debug", &::pugi::xml_node::offset_debug)
						.def("hash_value", &::pugi::xml_node::hash_value)
						/*.def("internal_object", &::pugi::xml_node::internal_object)*/,

					class_<::pugi::xml_node_iterator>("node_iterator")
						.def(constructor<>())
						.def(constructor<const ::pugi::xml_node&>()),

					class_<::pugi::xml_attribute_iterator>("attribute_iterator")
						.def(constructor<>())
						.def(constructor<const ::pugi::xml_attribute&, const ::pugi::xml_node&>()),

					/*class_<::pugi::xml_tree_walker>("tree_walker")
						.def(constructor<>())
						.def("begin", &::pugi::xml_tree_walker::begin)
						.def("for_each", &::pugi::xml_tree_walker::for_each)
						.def("end", &::pugi::xml_tree_walker::end)*/

					class_<::pugi::xml_parse_result>("parse_result")
						.def(constructor<>())
						.def_readonly("status", &::pugi::xml_parse_result::status)
						.def_readonly("encoding", &::pugi::xml_parse_result::encoding)
						.def("description", &::pugi::xml_parse_result::description),

					class_<::pugi::xml_document, bases<::pugi::xml_node> >("document")
						.def(constructor<>())
						.def("reset", (void(::pugi::xml_document::*)())&::pugi::xml_document::reset)
						.def("reset", (void(::pugi::xml_document::*)(const ::pugi::xml_document&))&::pugi::xml_document::reset)
						.def("load", (::pugi::xml_parse_result(::pugi::xml_document::*)(const ::pugi::char_t*, unsigned int))&::pugi::xml_document::load)
						.def("load", (::pugi::xml_parse_result(::pugi::xml_document::*)(std::basic_istream<char, std::char_traits<char> >&, unsigned int, ::pugi::xml_encoding))&::pugi::xml_document::load)
						.def("load", (::pugi::xml_parse_result(::pugi::xml_document::*)(std::basic_istream<wchar_t, std::char_traits<wchar_t> >&, unsigned int))&::pugi::xml_document::load)
						.def("load_file", (::pugi::xml_parse_result(::pugi::xml_document::*)(const char*, unsigned int, ::pugi::xml_encoding))&::pugi::xml_document::load_file)
						.def("load_file", (::pugi::xml_parse_result(::pugi::xml_document::*)(const wchar_t*, unsigned int, ::pugi::xml_encoding))&::pugi::xml_document::load_file)
						.def("load_buffer", &::pugi::xml_document::load_buffer)
						.def("load_buffer_inplace", &::pugi::xml_document::load_buffer_inplace)
						.def("load_buffer_inplace_own", &::pugi::xml_document::load_buffer_inplace_own)
						.def("save", (void(::pugi::xml_document::*)(::pugi::xml_writer&, const ::pugi::char_t*, unsigned int, ::pugi::xml_encoding)const)&::pugi::xml_document::save)
						.def("save", (void(::pugi::xml_document::*)(std::basic_ostream<char, std::char_traits<char> >&, const ::pugi::char_t*, unsigned int, ::pugi::xml_encoding)const)&::pugi::xml_document::save)
						.def("save", (void(::pugi::xml_document::*)(std::basic_ostream<wchar_t, std::char_traits<wchar_t> >&, const ::pugi::char_t*, unsigned int)const)&::pugi::xml_document::save)
						.def("save_file", (bool(::pugi::xml_document::*)(const char*, const ::pugi::char_t*, unsigned int, ::pugi::xml_encoding)const)&::pugi::xml_document::save_file)
						.def("save_file", (bool(::pugi::xml_document::*)(const wchar_t*, const ::pugi::char_t*, unsigned int, ::pugi::xml_encoding)const)&::pugi::xml_document::save_file)
						.def("document_element", &::pugi::xml_document::document_element)

					/*
					_class<::pugi::xpath_parse_result>("xpath_parse_result")
					*/
				];

			object node_type = newtable(lua);
			node_type["node_null"] = ::pugi::xml_node_type::node_null;
			node_type["node_document"] = ::pugi::xml_node_type::node_document;
			node_type["node_element"] = ::pugi::xml_node_type::node_element;
			node_type["node_pcdata"] = ::pugi::xml_node_type::node_pcdata;
			node_type["node_cdata"] = ::pugi::xml_node_type::node_cdata;
			node_type["node_comment"] = ::pugi::xml_node_type::node_comment;
			node_type["node_pi"] = ::pugi::xml_node_type::node_pi;
			node_type["node_declaration"] = ::pugi::xml_node_type::node_declaration;
			node_type["node_doctype"] = ::pugi::xml_node_type::node_doctype;
			//globals(lua)[ns.c_str()]["node_type"] = node_type;

			object encoding = newtable(lua);
			encoding["auto"] = ::pugi::xml_encoding::encoding_auto;
			encoding["utf8"] = ::pugi::xml_encoding::encoding_utf8;
			encoding["utf16_le"] = ::pugi::xml_encoding::encoding_utf16_le;
			encoding["utf16_be"] = ::pugi::xml_encoding::encoding_utf16_be;
			encoding["utf16"] = ::pugi::xml_encoding::encoding_utf16;
			encoding["utf32_le"] = ::pugi::xml_encoding::encoding_utf32_le;
			encoding["utf32_be"] = ::pugi::xml_encoding::encoding_utf32_be;
			encoding["utf32"] = ::pugi::xml_encoding::encoding_utf32;
			encoding["wchar"] = ::pugi::xml_encoding::encoding_wchar;
			//globals(lua)[ns.c_str()]["encoding"] = encoding;

			/*object parse_status = newtable(lua);
			parse_status["ok"] = ::pugi::xml_parse_status::status_ok;
			parse_status["file_not_found"] = ::pugi::xml_parse_status::status_file_not_found;
			parse_status["io_error"] = ::pugi::status_io_error;
			parse_status["out_of_memory"] = ::pugi::status_out_of_memory;
			parse_status["internal_error"] = ::pugi::status_internal_error;
			parse_status["unrecognized_tag"] = ::pugi::status_unrecognized_tag;
			parse_status["bad_pi"] = ::pugi::status_bad_pi;
			parse_status["bad_comment"] = ::pugi::status_bad_comment;
			parse_status["bad_cdata"] = ::pugi::status_bad_cdata;
			parse_status["bad_doctype"] = ::pugi::status_bad_doctype;
			parse_status["bad_pcdata"] = ::pugi::status_bad_pcdata;
			parse_status["bad_start_element"] = ::pugi::status_bad_start_element;
			parse_status["bad_attribute"] = ::pugi::status_bad_attribute;
			parse_status["bad_end_element"] = ::pugi::status_bad_end_element;
			parse_status["end_element_mismatch"] = ::pugi::status_end_element_mismatch;*/
			//globals(lua)[ns.c_str()]["parse_status"] = parse_status;
		}
	}
}